#include "MapFix.h"
#include <math.h>

//CMapFix* CMapFix::m_pInstance = NULL;
CMapFix::CMapFix()
{
	m_casm_f = 0.0;
	m_casm_rr = 0.0;
	m_casm_t1 = 0.0;
	m_casm_t2 = 0.0;
	m_casm_x1 = 0.0;
	m_casm_x2 = 0.0;
	m_casm_y1 = 0.0;
	m_casm_y2 = 0.0;
}

//纠偏计算
//dSrcLat 纠偏之前的纬度，dSrcLong纠偏之前的经度
//dDstLat 纠偏之后的纬度，dDstLong纠偏之后的经度（这两个作为返回值使用）
void CMapFix::GPSFix(double dSrcLat, double dSrcLong, double& dDstLat, double& dDstLong)
{
	try
	{
		double num = dSrcLong * 3686400.0;
		double num2 = dSrcLat * 3686400.0;
		double num3 = 0.0;
		double num4 = 0.0;
		double num5 = 0.0;
		MapPoint* point = wgtochina_lb(1, (int)num, (int)num2, (int)num5, (int)num3, (int)num4);
		if (point == NULL)
		{
			dDstLong = dSrcLong;
			dDstLat = dSrcLat;
		}
		else
		{
			double num6 = point->dLongitude;
			double num7 = point->dLatitude;
			num6 /= 3686400.0;
			num7 /= 3686400.0;
			dDstLong = num6;
			dDstLat = num7;
			delete point;
		}
	}
	catch (int e )
	{
	}
	catch (...)
	{

	}
}

void CMapFix::IniCasm(double w_time, double w_lng, double w_lat)
{
	m_casm_t1 = w_time;
	m_casm_t2 = w_time;
	double num = (int)(w_time / 0.357);
	m_casm_rr = w_time - (num * 0.357);
	if (w_time == 0.0)
	{
		m_casm_rr = 0.3;
	}
	m_casm_x1 = w_lng;
	m_casm_y1 = w_lat;
	m_casm_x2 = w_lng;
	m_casm_y2 = w_lat;
	m_casm_f = 3.0;
}
double CMapFix::random_yj()
{
	double num = 314159269.0;
	double num2 = 453806245.0;
	m_casm_rr = (num * m_casm_rr) + num2;
	double num3 = (int)(m_casm_rr / 2.0);
	m_casm_rr -= num3 * 2.0;
	m_casm_rr /= 2.0;
	return m_casm_rr;
}
double CMapFix::Transform_jy5(double x, double xx)
{
	double num = 6378245.0;
	double num2 = 0.00669342;
	double num3 = sqrt(1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433)));
	return ((xx * 180.0) / (((num / num3) * cos(x * 0.0174532925199433)) * 3.1415926));
}
double CMapFix::Transform_jyj5(double x, double yy)
{
	double num = 6378245.0;
	double num2 = 0.00669342;
	double d = 1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433));
	double num4 = (num * (1.0 - num2)) / (d * sqrt(d));
	return ((yy * 180.0) / (num4 * 3.1415926));
}
double CMapFix::Transform_yj5(double x, double y)
{
	double num = ((((300.0 + (1.0 * x)) + (2.0 * y)) + ((0.1 * x) * x)) + ((0.1 * x) * y)) + (0.1 * sqrt(sqrt(x * x)));
	num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588* x))) * 0.6667;
	num += ((20.0 * yj_sin2(3.141592653589794 * x)) + (40.0 * yj_sin2(1.0471975511965981* x))) * 0.6667;
	return (num + (((150.0 * yj_sin2(0.26179938779914952 * x)) + (300.0 * yj_sin2(0.10471975511965979 * x))) * 0.6667));
}
double CMapFix::Transform_yjy5(double x, double y)
{
	double num = ((((-100.0 + (2.0 * x)) + (3.0 * y)) + ((0.2 * y) * y)) + ((0.1 * x) * y)) + (0.2 * sqrt(sqrt(x * x)));
	num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588* x))) * 0.6667;
	num += ((20.0 * yj_sin2(3.141592653589794 * y)) + (40.0 * yj_sin2(1.0471975511965981* y))) * 0.6667;
	return (num + (((160.0 * yj_sin2(0.26179938779914952 * y)) + (320.0 * yj_sin2(0.10471975511965979 * y))) * 0.6667));
}
CMapFix::MapPoint* CMapFix::wgtochina_lb(int wg_flag, int wg_lng, int wg_lat, int wg_heit, int wg_week, int wg_time)
{
	MapPoint* pPoint = NULL;
	if (wg_heit <= 0x1388)
	{
		double num = wg_lng;
		num /= 3686400.0;
		double x = wg_lat;
		x /= 3686400.0;
		if (num < 72.004)
		{
			return pPoint;
		}
		if (num > 137.8347)
		{
			return pPoint;
		}
		if (x < 0.8293)
		{
			return pPoint;
		}
		if (x > 55.8271)
		{
			return pPoint;
		}
		if (wg_flag == 0)
		{
			IniCasm((double)wg_time, (double)wg_lng, (double)wg_lat);
			pPoint = new MapPoint();
			pPoint->dLatitude = ((double)wg_lng);
			pPoint->dLongitude = ((double)wg_lat);
			return pPoint;
		}
		m_casm_t2 = wg_time;
		double num3 = (m_casm_t2 - m_casm_t1) / 1000.0;
		if (num3 <= 0.0)
		{
			m_casm_t1 = m_casm_t2;
			m_casm_f++;
			m_casm_x1 = m_casm_x2;
			m_casm_f++;
			m_casm_y1 = m_casm_y2;
			m_casm_f++;
		}
		else if (num3 > 120.0)
		{
			if (m_casm_f == 3.0)
			{
				m_casm_f = 0.0;
				m_casm_x2 = wg_lng;
				m_casm_y2 = wg_lat;
				double num4 = m_casm_x2 - m_casm_x1;
				double num5 = m_casm_y2 - m_casm_y1;
				double num6 = sqrt((num4 * num4) + (num5 * num5)) / num3;
				if (num6 > 3185.0)
				{
					return pPoint;
				}
			}
			m_casm_t1 = m_casm_t2;
			m_casm_f++;
			m_casm_x1 = m_casm_x2;
			m_casm_f++;
			m_casm_y1 = m_casm_y2;
			m_casm_f++;
		}
		double xx = Transform_yj5(num - 105.0, x - 35.0);
		double yy = Transform_yjy5(num - 105.0, x - 35.0);
		double num9 = wg_heit;
		xx = ((xx + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj();
		yy = ((yy + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj();
		pPoint = new MapPoint();
		pPoint->dLongitude = ((num + Transform_jy5(x, xx)) * 3686400.0);
		pPoint->dLatitude = ((x + Transform_jyj5(x, yy)) * 3686400.0);
	}
	return pPoint;
}
double CMapFix::yj_sin2(double x)
{
	double num = 0.0;
	if (x < 0.0)
	{
		x = -x;
		num = 1.0;
	}
	int num2 = (int)(x / 6.28318530717959);
	double num3 = x - (num2 * 6.28318530717959);
	if (num3 > 3.1415926535897931)
	{
		num3 -= 3.1415926535897931;
		if (num == 1.0)
		{
			num = 0.0;
		}
		else if (num == 0.0)
		{
			num = 1.0;
		}
	}
	x = num3;
	double num4 = x;
	double num5 = x;
	num3 *= num3;
	num5 *= num3;
	num4 -= num5 * 0.166666666666667;
	num5 *= num3;
	num4 += num5 * 0.00833333333333333;
	num5 *= num3;
	num4 -= num5 * 0.000198412698412698;
	num5 *= num3;
	num4 += num5 * 2.75573192239859E-06;
	num5 *= num3;
	num4 -= num5 * 2.50521083854417E-08;
	if (num == 1.0)
	{
		num4 = -num4;
	}
	return num4;
}